package com.admin.education.dataTransferObject.templates.Mapper;

import com.admin.education.common.exceptions.BadRequestException;
import com.admin.education.dataTransferObject.applyCrowds.Mapper.ApplyCrowdsMapper;
import com.admin.education.dataTransferObject.categorys.Mapper.CategoryMapper;
import com.admin.education.dataTransferObject.question.Mapper.QuestionMapper;
import com.admin.education.dataTransferObject.question.QuestionTransfer;
import com.admin.education.dataTransferObject.templates.Request.CreateTemplateRequest;
import com.admin.education.dataTransferObject.templates.Request.UpdateTemplateRequest;
import com.admin.education.dataTransferObject.templates.TemplatesTransfer;
import com.admin.education.models.*;
import com.admin.education.models.Mapper.TemplateQuestionMapper;
import com.admin.education.repositories.*;
import lombok.extern.slf4j.Slf4j;
import org.mapstruct.*;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;

@Mapper
@Slf4j
public abstract class TemplatesMapper {

    private QQuestions qQuestions;
    private QRole qRole;
    private QCategorys qCategorys;

    public TemplatesMapper() {
        qQuestions = QQuestions.questions;
        qCategorys = QCategorys.categorys;
        qRole = QRole.role;
    }

    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private QuestionRepository questionRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private CategorysRepository categorysRepository;
    @Autowired
    private TemplateQuestionMapper templateQuestionMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private ApplyCrowdsMapper applyCrowdsMapper;
    @Mappings({
            @Mapping(target = "questions", ignore = true),
            @Mapping(target = "root", ignore = true),
            @Mapping(target = "applyCrowds",ignore = true),
            @Mapping(target = "categorys",ignore = true)
    })
    public abstract TemplatesTransfer mapFrom(Templates templates);

    @Mappings({
            @Mapping(target = "questions", ignore = true),
            @Mapping(target = "root", ignore = true)
    })
    public abstract TemplatesTransfer mapFrom(Templates templates, @MappingTarget TemplatesTransfer templatesTransfer);

    @Mappings({})
    public abstract List<TemplatesTransfer> mapFrom(List<Templates> templates);

    @Mappings({
            @Mapping(target = "categorys", ignore = true),
            @Mapping(target = "applyCrowds", ignore = true)
    })
    public abstract Templates mapFrom(CreateTemplateRequest createTemplateRequest) throws BadRequestException;

    @AfterMapping
    public void afterMapping(CreateTemplateRequest createTemplateRequest, @MappingTarget Templates templates) throws BadRequestException {
        templates.setCreateTime(new Date());
            templates.setApplyCrowds(new ArrayList<>());
            templates.setCategorys(new ArrayList<>());
        templates.setTemplateQuestions(new ArrayList<>());
        templates.setValid(true);

        if (null != createTemplateRequest.getApplyCrowds())
            for (Long roleId : createTemplateRequest.getApplyCrowds()) {
                Role role = this.roleRepository.findById(roleId);
                if (null == role) {
                    throw new BadRequestException("角色不存在");
                }
                if (role.isAdminManage()) {
                    throw new BadRequestException("不可添加后台角色");
                }

                ApplyCrowd applyCrowd = new ApplyCrowd();
                applyCrowd.setRole(role);
                applyCrowd.setTemplates(templates);

                templates.getApplyCrowds().add(applyCrowd);

            }

        if (null != createTemplateRequest.getCategorys())
            for (Long categoryId : createTemplateRequest.getCategorys()) {
                Categorys categorys = this.categorysRepository.findById(categoryId);
                if (null == categorys) {
                    throw new BadRequestException("分类不存在");
                }

                templates.getCategorys().add(categorys);
                categorys.getTemplates().add(templates);
            }

        if (null != createTemplateRequest.getQuestions()) {
            templates.setTemplateMark(BigDecimal.ZERO);
            for (Long questionId : createTemplateRequest.getQuestions()) {
                Questions questions = this.questionRepository.findById(questionId);
                if (null == questions) {
                    throw new BadRequestException("问题不存在");
                }

                TemplateQuestions templateQuestions = templateQuestionMapper.mapFrom(questions);

                templateQuestions.setTemplates(templates);

                templates.getTemplateQuestions().add(templateQuestions);

                if(null!=questions.getMark()){
                    templates.setTemplateMark(templates.getTemplateMark().add(questions.getMark()));
                }
            }
        }

    }

    @Mappings({
            @Mapping(target = "categorys", ignore = true),
            @Mapping(target = "applyCrowds", ignore = true)
    })
    public abstract Templates mapFrom(UpdateTemplateRequest updateTemplateRequest, @MappingTarget Templates templates) throws BadRequestException;

    @AfterMapping
    public void afterMapping(UpdateTemplateRequest updateTemplateRequest, @MappingTarget Templates templates) throws BadRequestException {
        templates.setModifyTime(new Date());

        if (null != updateTemplateRequest.getApplyCrowds())
            for (Long roleId : updateTemplateRequest.getApplyCrowds()) {
                Role role = this.roleRepository.findById(roleId);
                if (null == role) {
                    throw new BadRequestException("角色不存在");
                }
                if (role.isAdminManage()) {
                    throw new BadRequestException("不可添加后台角色");
                }

                ApplyCrowd applyCrowd = new ApplyCrowd();
                applyCrowd.setRole(role);
                applyCrowd.setTemplates(templates);

                templates.getApplyCrowds().add(applyCrowd);
            }

        if (null != updateTemplateRequest.getCategorys())
            for (Long categoryId : updateTemplateRequest.getCategorys()) {
                Categorys categorys = this.categorysRepository.findById(categoryId);
                if (null == categorys) {
                    throw new BadRequestException("分类不存在");
                }

                templates.getCategorys().add(categorys);
                categorys.getTemplates().add(templates);
            }

        if (null != updateTemplateRequest.getQuestions()) {
            templates.setTemplateMark(BigDecimal.ZERO);
            for (Long questionId : updateTemplateRequest.getQuestions()) {
                Questions questions = this.questionRepository.findById(questionId);
                if (null == questions) {
                    throw new BadRequestException("问题不存在");
                }

                TemplateQuestions templateQuestions = templateQuestionMapper.mapFrom(questions);

                templateQuestions.setTemplates(templates);

                templates.getTemplateQuestions().add(templateQuestions);

                if(null!=questions.getMark()){
                    templates.setTemplateMark(templates.getTemplateMark().add(questions.getMark()));
                }
            }

        }
    }

    @AfterMapping
    public void afterMapping(Templates templates, @MappingTarget TemplatesTransfer templatesTransfer) {
        if (templatesTransfer.isRoot() && null != templates.getTemplateQuestions()) {
            long seed = System.nanoTime();
            List<QuestionTransfer> questionTransfers = questionMapper.mapFromTemplate(templates.getTemplateQuestions());
            Collections.shuffle(questionTransfers, new Random(seed));
            templatesTransfer.setQuestions(questionTransfers);
        }

        if(templatesTransfer.isRoot()&&null!=templates.getApplyCrowds()){
            templatesTransfer.setApplyCrowds(applyCrowdsMapper.mapFrom(templates.getApplyCrowds()));
        }
        if(templatesTransfer.isRoot()&&null!=templates.getCategorys()){
            templatesTransfer.setCategorys(categoryMapper.mapFrom(templates.getCategorys()));
        }
    }
}
